home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / source / ControlStore.c < prev    next >
Encoding:
Text File  |  1994-10-04  |  12.0 KB  |  470 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    "UtilsSys7.h"
  13. #include    "Globals.h"
  14. #include    "Animation.h"
  15. #include    "ControlStore.h"
  16. #include    "DoMenu.h"
  17. #include    "Microprogram_Ed.h"
  18. #include    "SimUtils.h"
  19.  
  20. #if defined(FabSystem7orlater)
  21.  
  22. #pragma segment Rare
  23.  
  24. const short controlStoreObject[] = {kP_CONTSTORE, 0 };
  25.  
  26. short    myFileRefN;
  27. Boolean    DocIsOpen;
  28.  
  29. static FSSpec    workingFile;
  30. static ScriptCode    wkFileScript;
  31. static Boolean    dirtyCSFlag = false;
  32.  
  33. /*====== internal routines ======*/
  34. static OSErr gotSave(Handle buf);
  35. static OSErr gotSaveAs(Handle buf);
  36. static OSErr SafeSave(Handle wrBuf, FSSpec *onWhichFile, ScriptCode);
  37.  
  38. /* RevertFile: we revert to the last saved version of the doc */
  39.  
  40. OSErr RevertFile(void)
  41. {
  42. FSSpec    tempNewFile = workingFile;
  43.  
  44. FSClose(myFileRefN);
  45. myFileRefN = 0;
  46. DocumentIsDirty(false);
  47. return myOpenCSFile(&tempNewFile, wkFileScript, false);
  48. }
  49.  
  50. /* myOpenCSFile: we read all that stuff (the microprogram) from the file */
  51.  
  52. OSErr myOpenCSFile(FSSpec *theFile, ScriptCode theScript, Boolean StationeryDoc)
  53. {
  54. Str255    tempS;
  55. ParamBlockRec    myPB;
  56. EventRecord    dummyEv;
  57. Rect    tempRect;
  58. GrafPtr    savePort;
  59. register Handle    tempBuffer;
  60. unsigned long    fileSize;
  61. short    length;
  62. register OSErr    err;
  63. register Boolean    isLocked = false;
  64.  
  65. SetCursor(*gWatchHandle);
  66. GetPort(&savePort);
  67. SetPort(gWPtr_Microprogram_Ed);
  68. if ((err = FSpOpenDF(theFile, StationeryDoc ? fsRdPerm : fsRdWrPerm, &myFileRefN)) == permErr) {
  69.     err = FSpOpenDF(theFile, fsRdPerm, &myFileRefN);
  70.     isLocked = true;
  71.     }
  72. if (err == noErr) {
  73.     if ((err = GetEOF(myFileRefN, (long *)&fileSize)) == noErr) {
  74.         if ((tempBuffer = NewHandleGeneral(fileSize)) != 0L) {
  75.             myPB.ioParam.ioCompletion = 0L;
  76.             myPB.ioParam.ioRefNum = myFileRefN;
  77.             HLock(tempBuffer);
  78.             myPB.ioParam.ioBuffer = *tempBuffer;
  79.             myPB.ioParam.ioReqCount = fileSize;
  80.             myPB.ioParam.ioPosMode = fsFromStart;
  81.             myPB.ioParam.ioPosOffset = 0L;
  82.             (void)PBReadAsync(&myPB);
  83.             while (myPB.ioParam.ioResult > 0) {
  84.                 SystemTask();
  85.                 (void)EventAvail(everyEvent, &dummyEv);
  86.                 }
  87.             HUnlock(tempBuffer);
  88.             if ((err = myPB.ioParam.ioResult) == noErr) {
  89.                 Point    tempCell;
  90.                 register unsigned char *spanningPtr;
  91.                 register short    i;
  92.  
  93.                 LDoDraw(false, Lists[kL_COMMENTS]);
  94.                 DoNew();
  95.                 BlockMoveData(*tempBuffer, gCsMemory, kSIZE_CSMEM + kSIZE_ASSMEM);
  96.                 tempCell.h = 0;
  97.                 HLock(tempBuffer);
  98.                 for (spanningPtr = (unsigned char *)*tempBuffer + kSIZE_CSMEM + kSIZE_ASSMEM,
  99.                     i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  100.  
  101.                     tempCell.v = i;
  102.                     LSetCell(spanningPtr + 1, *spanningPtr, tempCell, Lists[kL_COMMENTS]);
  103.                     spanningPtr += *spanningPtr + 1;
  104.                     }
  105.                 HUnlock(tempBuffer);
  106.                 LDoDraw(true, Lists[kL_COMMENTS]);
  107.                 if (StationeryDoc == false) {
  108.                     workingFile = *theFile;
  109.                     wkFileScript = theScript;
  110.                     SetWTitle(gWPtr_Microprogram_Ed, theFile->name);
  111.                     }
  112.                 DocumentIsDirty(false);
  113.             /* get cell contents and put into TextEdit field */
  114.                 length = 255;    /* maximum length of text */
  115.                 tempCell.h = 0;
  116.                 tempCell.v = theSelection[kL_COMMENTS];
  117.                 LGetCell(&tempS, &length, tempCell, Lists[kL_COMMENTS]);
  118.                 TESetText(&tempS, length, TEs[kKEY_COMMENT]);
  119.                 RefreshTE(kKEY_COMMENT);
  120.         //        UnloadSeg(RefreshTE);
  121.                 SetMir((*(gCsMemory + theSelection[kL_COMMENTS])).cstore);
  122.                 tempRect = *keyrects[kKEY_LIST];
  123.                 tempRect.right -= kScrollbarAdjust;
  124.                 InvalRect(&tempRect);
  125.                 DoMenuWindows(kMItem_Microprogram);
  126.                 }
  127.             DisposHandle(tempBuffer);
  128.             }
  129.         else err = MemError();
  130.         }
  131.     if (err || StationeryDoc || isLocked)
  132.         (void)FSClose(myFileRefN);
  133.     }
  134. if (err || StationeryDoc || isLocked)
  135.     myFileRefN = 0;
  136. SetPort(savePort);
  137. InitCursor();
  138. return err;
  139. }
  140.  
  141. /* mySaveCSFile: the user has chosen Save or Save As… from the menus */
  142.  
  143. OSErr mySaveCSFile(short selector)
  144. {
  145. Point    tempCell;
  146. register Handle    readyBuffer;
  147. register OSErr    err;
  148.  
  149. SetCursor(*gWatchHandle);
  150. tempCell.h = 0;
  151. tempCell.v = theSelection[kL_COMMENTS];
  152. ChangedListSelection(tempCell, kL_COMMENTS, false);
  153. if (readyBuffer = PrepareBufferFromList()) {
  154.     switch (selector) {
  155.         case kGOT_SAVE: err = gotSave(readyBuffer);
  156.             break;
  157.         case kGOT_SAVEAS: err = gotSaveAs(readyBuffer);
  158.         }
  159.     DisposHandle(readyBuffer);
  160.     }
  161. else err = MemError();
  162. InitCursor();
  163. return err;
  164. }
  165.  
  166. /* gotSave: the user has told us to Save. Is he working at a previously saved
  167. document or not? */
  168.  
  169. static OSErr gotSave(Handle buf)
  170. {
  171. register OSErr    err;
  172.  
  173. if (myFileRefN != 0)
  174.     err = SafeSave(buf, &workingFile, wkFileScript);
  175. else
  176.     err = gotSaveAs(buf);
  177. return err;
  178. }
  179.  
  180. /* gotSaveAs: we must definitely show up the dialog box for "save-a-file"
  181. and save it if asked for */
  182.  
  183. static OSErr gotSaveAs(Handle buf)
  184. {
  185. enum {
  186. kSTR_CSPROMPT = 135,
  187. kSTR_CSDEFNAME
  188. };
  189.  
  190. StandardFileReply    mySFR;
  191. register Handle    sH1;
  192. register Handle    sH2;
  193. short    tmpFRefN;
  194. register SignedByte    state1, state2;
  195. register OSErr    err;
  196.  
  197. state1 = WantThisHandleSafe(sH1 = (Handle)GetString(kSTR_CSPROMPT));
  198. state2 = WantThisHandleSafe(sH2 = (Handle)GetString(kSTR_CSDEFNAME));
  199. InitCursor();
  200. StandardPutFile((ConstStr255Param)*sH1, (ConstStr255Param)*sH2, &mySFR);
  201. SetCursor(*gWatchHandle);
  202. if (mySFR.sfGood) {
  203.     if (mySFR.sfReplacing)
  204.         err = SafeSave(buf, &mySFR.sfFile, mySFR.sfScript);
  205. /* not replacing an existing file */
  206.     else if ((err = FSpCreate(&mySFR.sfFile, kFCR_MINE, kFTY_CSTORE, mySFR.sfScript)) == noErr)
  207.         if ((err = FSpOpenDF(&mySFR.sfFile, fsRdWrPerm, &tmpFRefN)) == noErr)
  208.             if ((err = WriteMicroprogramData(buf, &mySFR.sfFile, tmpFRefN, mySFR.sfScript)) == noErr) {
  209.                 if (myFileRefN)    /* close old working file if any */
  210.                     (void)FSClose(myFileRefN);
  211.                 myFileRefN = tmpFRefN;    /* this is the new work file */
  212.                 workingFile = mySFR.sfFile;
  213.                 wkFileScript = mySFR.sfScript;
  214.                 SetWTitle(gWPtr_Microprogram_Ed, mySFR.sfFile.name);
  215.                 DocumentIsDirty(false);
  216.                 }
  217.             else {    /* error writing data */
  218.                 (void)FSClose(tmpFRefN);
  219.                 (void)FSpDelete(&mySFR.sfFile);
  220.                 }
  221.     }
  222. else err = 1;
  223. HSetState(sH1, state1);
  224. HSetState(sH2, state2);
  225. return(err);
  226. }
  227.  
  228. /* SafeSave: we should do a safe save of the document
  229. (a previously saved version already exists) */
  230.  
  231. OSErr SafeSave(Handle buf, FSSpec *onWhichFile, ScriptCode myFScript)
  232. {
  233. Str255    tempFName;
  234. FSSpec    thisFSSpec;
  235. long    thisDirID;
  236. short    thisVRefNum, newFileRefn;
  237. register OSErr    err;
  238.  
  239. if (0)    /* test if file locked (FSpExchange does not) */
  240.     err = fLckdErr;
  241. else {
  242.     MyNumToString(TickCount(), tempFName);
  243.     if ((err = FindFolder(onWhichFile->vRefNum, kTemporaryFolderType, kCreateFolder,
  244.                     &thisVRefNum, &thisDirID)) == noErr) {
  245.         (void)FSMakeFSSpec(thisVRefNum, thisDirID, (ConstStr255Param)&tempFName, &thisFSSpec);
  246.         if ((err = FSpCreate(&thisFSSpec, kFCR_MINE, kFTY_CSTORE,
  247.                             myFScript)) == noErr)
  248.             if ((err = FSpOpenDF(&thisFSSpec, fsRdWrPerm, &newFileRefn)) == noErr)
  249.                 if ((err = WriteMicroprogramData(buf, &thisFSSpec, newFileRefn, myFScript)) == noErr) {
  250.                     if ((err = FSpExchangeFiles(&thisFSSpec, onWhichFile)) == noErr) {
  251.                         if (myFileRefN)
  252.                             (void)FSClose(myFileRefN);
  253.                         myFileRefN = newFileRefn;
  254.                         workingFile = *onWhichFile;
  255.                         wkFileScript = myFScript;
  256.                         SetWTitle(gWPtr_Microprogram_Ed, onWhichFile->name);
  257.                         DocumentIsDirty(false);
  258.                         err = FSpDelete(&thisFSSpec);
  259.                         }
  260.                     }
  261.                 else {
  262.                     (void)FSClose(newFileRefn);
  263.                     (void)FSpDelete(&thisFSSpec);    // the temporary one
  264.                     if (err == dskFulErr) {
  265.                         InitCursor();
  266.                         (void)StopAlert_UPP(kALRT_NOSAVE, myStdFilterProcNoCancel);
  267.                         err = 1;
  268.                         }
  269.                     }
  270.         }
  271.     }
  272. return(err);
  273. }
  274.  
  275. /* WriteMicroprogramData: writes physically the data into the file */
  276.  
  277. OSErr WriteMicroprogramData(Handle prepBuffer, FSSpec *theFSpec, short theOpenedFile,
  278.                         ScriptCode theFileSc)
  279. {
  280. ParamBlockRec    myPB;
  281. EventRecord    dummyEv;
  282. register OSErr    err;
  283.  
  284. myPB.ioParam.ioCompletion = 0L;
  285. myPB.ioParam.ioBuffer = (Ptr)gCsMemory;
  286. myPB.ioParam.ioReqCount = kSIZE_CSMEM + kSIZE_ASSMEM;
  287. myPB.ioParam.ioPosMode = fsFromStart;
  288. myPB.ioParam.ioRefNum = theOpenedFile;
  289. myPB.ioParam.ioPosOffset = 0L;
  290. (void)PBWriteAsync(&myPB);
  291. while (myPB.ioParam.ioResult > 0) {
  292.     SystemTask();
  293.     (void)EventAvail(everyEvent, &dummyEv);
  294.     }
  295. if ((err = myPB.ioParam.ioResult) == noErr) {
  296.     myPB.ioParam.ioBuffer = *prepBuffer;
  297.     myPB.ioParam.ioReqCount = InlineGetHandleSize(prepBuffer);
  298.     myPB.ioParam.ioPosMode = fsAtMark;
  299.     myPB.ioParam.ioRefNum = theOpenedFile;
  300.     myPB.ioParam.ioPosOffset = 0L;
  301.     HLock(prepBuffer);
  302.     (void)PBWriteAsync(&myPB);
  303.     while (myPB.ioParam.ioResult > 0) {
  304.         SystemTask();
  305.         (void)EventAvail(everyEvent, &dummyEv);
  306.         }
  307.     HUnlock(prepBuffer);
  308.     if ((err = myPB.ioParam.ioResult) == noErr)
  309.         err = AddSTRRes2Doc(theFSpec, kFCR_MINE, kFTY_CSTORE, kSTR_ApplicationName, theFileSc);
  310.     }
  311. return err;
  312. }
  313.  
  314. /* DoNew: starts afresh with a new microprogram */
  315.  
  316. void DoNew(void)
  317. {
  318. enum {
  319. kSTR_UNTITLED = 137
  320. };
  321.  
  322. register Handle    UntitledStr;
  323. register SignedByte    oldstate;
  324.  
  325. ResetMicroprogramWindow();
  326. DocIsOpen = true;
  327. ActivateObjs(controlStoreObject);
  328. oldstate = WantThisHandleSafe(UntitledStr = (Handle)GetString(kSTR_UNTITLED));
  329. SetWTitle(gWPtr_Microprogram_Ed, (ConstStr255Param)*UntitledStr);
  330. (void) PLstrcpy(workingFile.name, (ConstStr255Param)*UntitledStr);
  331. HSetState(UntitledStr, oldstate);
  332. }
  333.  
  334. /* ResetMicroprogramWindow: wipes out the window to an empty one */
  335.  
  336. void ResetMicroprogramWindow(void)
  337. {
  338. Str255    tempS;
  339. register Point tempCell = { 0, 0};
  340. short    leng;
  341. register short    i;
  342.  
  343. for ( i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  344.     tempCell.v = i;
  345.     LClrCell(tempCell, Lists[kL_COMMENTS]);
  346.     }
  347. tempCell.v = 0;
  348. leng = 255;
  349. LGetCell(&tempS, &leng, tempCell, Lists[kL_COMMENTS]);
  350. TESetText(&tempS, leng, TEs[kKEY_COMMENT]);
  351. keyDownDest = kKEY_BRTO;
  352.  
  353.     {
  354.     register union u_mir tempmir;
  355.  
  356.     tempmir.cstore = 0L;
  357.     tempmir.bits.c = 15;
  358.     tempmir.bits.dsc = 1;
  359.     SetControlsFromMir(tempmir);
  360. //    UnloadSeg(SetControlsFromMir);
  361.     }
  362. }
  363.  
  364. /* PrepareBufferFromList: sets up a buffer containing all the info
  365. about the microprogram, so that it is ready to be saved into a file. */
  366.  
  367. Handle PrepareBufferFromList(void)
  368. {
  369. Str255    tempS;
  370. Point    tempCell;
  371. register Handle    myH = nil;
  372. short    len;
  373. register OSErr    err;
  374. register short i;
  375.  
  376. if (Lists[kL_COMMENTS] && gCsMemory)
  377.     if (myH = NewHandleGeneral(0L)) {
  378.         tempCell.h = 0;
  379.         for (i = 0; i <= maxLLine[kL_COMMENTS]; i++) {
  380.             tempCell.v = i;
  381.             len = 255;
  382.             LGetCell(&tempS[1], &len, tempCell, Lists[kL_COMMENTS]);
  383.             tempS[0] = len;
  384.             if (err = PtrAndHand(&tempS, myH, len + 1))
  385.                 break;
  386.             }
  387.         if (err) {
  388.             DisposHandle(myH);
  389.             myH = nil;
  390.             }
  391.         }
  392. return myH;
  393. }
  394.  
  395. #pragma segment __%Main
  396.  
  397. /* ReadyToTerminate: we decide if we are ready to quit gracefully;
  398. shall we save an unsaved document? Let the user choose… */
  399.  
  400. Boolean ReadyToTerminate(void)
  401. {
  402. enum {
  403. kALRT_CPURUNNING = 143,
  404. kPUSH_SAVE = 1,
  405. kPUSH_CANCEL,
  406. kPUSH_DONTSAVE
  407. };
  408.  
  409. register OSErr    err;
  410.  
  411. if (gRstatus) {
  412.     InitCursor();
  413.     if (CautionAlert_UPP(kALRT_CPURUNNING, myStdFilterProc) == cancel)
  414.         return false;
  415.     }
  416. if (dirtyCSFlag) {
  417.     InitCursor();
  418.     ParamText(workingFile.name, nil, nil, nil);
  419.     switch (CautionAlert_UPP(kALRT_SAVE, myStdFilterProc)) {
  420.         case kPUSH_SAVE:
  421.             err = mySaveCSFile(kGOT_SAVE);
  422.             UnloadSeg(mySaveCSFile);
  423.             if (err) {
  424.                 if (err != 1)
  425.                     ErrorAlert(err);
  426.                 return false;
  427.                 }
  428.             break;
  429.         case kPUSH_CANCEL:
  430.             return false;
  431.             break;
  432.         case kPUSH_DONTSAVE:
  433.             break;
  434.         }
  435.     }
  436. if (myFileRefN) {
  437.     FSClose(myFileRefN);
  438.     myFileRefN = 0;
  439.     }
  440. DocumentIsDirty(false);
  441. DocIsOpen = false;
  442. DeactivateObjs(controlStoreObject);
  443. MyZeroBuffer((long *)gCsMemory, numOfLongs(kSIZE_ASSMEM + kSIZE_CSMEM));
  444. CloseMicroProg(gWPtr_Microprogram_Ed);
  445. SetMir(0L);
  446. return true;
  447. }
  448.  
  449. /* DocumentIsDirty: we are told if the document has been modified
  450. since last save. */
  451.  
  452. void DocumentIsDirty(Boolean dirtiness)
  453. {
  454. if (dirtyCSFlag != dirtiness) {
  455.     if (dirtyCSFlag = dirtiness) {
  456.         EnableItem(gMenu_File, kMItem_Save_Control_St);
  457.         }
  458.     else {
  459.         DisableItem(gMenu_File, kMItem_Save_Control_St);
  460.         }
  461.     if (myFileRefN && dirtyCSFlag)
  462.         EnableItem(gMenu_File, kMItem_Revert_to_Saved);
  463.     else
  464.         DisableItem(gMenu_File, kMItem_Revert_to_Saved);
  465.     }
  466. }
  467.  
  468. #endif
  469.  
  470.